import { EventEmitter } from 'events';
import { Logger } from '../logger';

/**
 * 插件性能指标
 */
export interface PluginMetrics {
  pluginId: string;
  methodName: string;
  executionTime: number;
  memoryUsage: number;
  timestamp: number;
  success: boolean;
  error?: string;
}

/**
 * 插件性能监控器
 */
export class PluginMonitor extends EventEmitter {
  private metrics: Map<string, PluginMetrics[]> = new Map();
  private readonly maxMetricsPerPlugin = 1000;
  private readonly performanceThreshold = 5000; // 5秒

  /**
   * 记录方法执行指标
   */
  recordMetrics(metrics: PluginMetrics): void {
    const pluginMetrics = this.metrics.get(metrics.pluginId) || [];
    pluginMetrics.push(metrics);

    // 保持指标数量在限制内
    if (pluginMetrics.length > this.maxMetricsPerPlugin) {
      pluginMetrics.shift();
    }

    this.metrics.set(metrics.pluginId, pluginMetrics);

    // 检查性能问题
    if (metrics.executionTime > this.performanceThreshold) {
      Logger.warn(`Plugin ${metrics.pluginId} method ${metrics.methodName} took ${metrics.executionTime}ms`);
      this.emit('performanceWarning', metrics);
    }

    // 记录错误
    if (!metrics.success && metrics.error) {
      Logger.error(`Plugin ${metrics.pluginId} method ${metrics.methodName} failed:`, metrics.error);
      this.emit('methodError', metrics);
    }

    this.emit('metricsRecorded', metrics);
  }

  /**
   * 获取插件指标
   */
  getPluginMetrics(pluginId: string): PluginMetrics[] {
    return this.metrics.get(pluginId) || [];
  }

  /**
   * 获取插件性能统计
   */
  getPluginStats(pluginId: string): {
    totalCalls: number;
    averageExecutionTime: number;
    successRate: number;
    slowestMethod: string | null;
    fastestMethod: string | null;
    errorCount: number;
  } {
    const metrics = this.getPluginMetrics(pluginId);
    
    if (metrics.length === 0) {
      return {
        totalCalls: 0,
        averageExecutionTime: 0,
        successRate: 0,
        slowestMethod: null,
        fastestMethod: null,
        errorCount: 0,
      };
    }

    const totalCalls = metrics.length;
    const successfulCalls = metrics.filter(m => m.success).length;
    const successRate = successfulCalls / totalCalls;
    const averageExecutionTime = metrics.reduce((sum, m) => sum + m.executionTime, 0) / totalCalls;
    const errorCount = metrics.filter(m => !m.success).length;

    // 找出最慢和最快的方法
    let slowestMethod: string | null = null;
    let fastestMethod: string | null = null;
    let maxTime = 0;
    let minTime = Infinity;

    const methodTimes = new Map<string, number[]>();
    metrics.forEach(m => {
      if (!methodTimes.has(m.methodName)) {
        methodTimes.set(m.methodName, []);
      }
      methodTimes.get(m.methodName)!.push(m.executionTime);
    });

    methodTimes.forEach((times, methodName) => {
      const avgTime = times.reduce((sum, time) => sum + time, 0) / times.length;
      if (avgTime > maxTime) {
        maxTime = avgTime;
        slowestMethod = methodName;
      }
      if (avgTime < minTime) {
        minTime = avgTime;
        fastestMethod = methodName;
      }
    });

    return {
      totalCalls,
      averageExecutionTime,
      successRate,
      slowestMethod,
      fastestMethod,
      errorCount,
    };
  }

  /**
   * 创建方法代理用于监控
   */
  createMethodProxy<T extends Function>(
    pluginId: string,
    methodName: string,
    originalMethod: T,
  ): T {
    return (async (...args: any[]) => {
      const startTime = Date.now();
      const startMemory = process.memoryUsage().heapUsed;
      
      try {
        const result = await originalMethod.apply(this, args);
        
        const endTime = Date.now();
        const endMemory = process.memoryUsage().heapUsed;
        
        this.recordMetrics({
          pluginId,
          methodName,
          executionTime: endTime - startTime,
          memoryUsage: endMemory - startMemory,
          timestamp: startTime,
          success: true,
        });
        
        return result;
      } catch (error) {
        const endTime = Date.now();
        const endMemory = process.memoryUsage().heapUsed;
        
        this.recordMetrics({
          pluginId,
          methodName,
          executionTime: endTime - startTime,
          memoryUsage: endMemory - startMemory,
          timestamp: startTime,
          success: false,
          error: error instanceof Error ? error.message : String(error),
        });
        
        throw error;
      }
    }) as T;
  }

  /**
   * 获取所有插件的性能报告
   */
  getPerformanceReport(): Record<string, any> {
    const report: Record<string, any> = {};
    
    for (const pluginId of this.metrics.keys()) {
      report[pluginId] = this.getPluginStats(pluginId);
    }
    
    return report;
  }

  /**
   * 清理插件指标
   */
  clearPluginMetrics(pluginId: string): void {
    this.metrics.delete(pluginId);
  }

  /**
   * 清理所有指标
   */
  clearAllMetrics(): void {
    this.metrics.clear();
  }
}